#pragma once

#ifdef __APPLE__
#define __OSX__
#endif
#ifdef WIN32
#define __WIN32__
#endif
#ifdef __linux__
#define __LINUX__
#endif

#include <iostream>
#include <cstring>

#ifdef __OSX__
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/event.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#endif
#ifdef __LINUX__
#include <sys/socket.h>
#include <sys/eventfd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <netdb.h>
#endif
#ifdef __WIN32__
#include <winsock.h>
#endif


#define ERR_SYNTAX "[syntax error]"
#define ERR_OPT "[wrong operator]"
#define ERR_TYPE "[wrong type]"
#define ERR_NOK "[No such key]"
#define ERR_CRE_OBJ "[cannot create obj]"

#define OPT_SUCC "success"
#define OPT_FAIL "failed"


#define LOG_ERR(MSG) (std::cerr << "[ERROR] " << (MSG) << " [file]" << __FILE__ << " [line]" << __LINE__ << " [function]" << __FUNCTION__ << "\n")
#define LOG_WARN(MSG) (std::cout << "[WARN] " << (MSG) << " [file]" << __FILE__ << " [line]" << __LINE__ << " [function]" << __FUNCTION__ << "\n")

#define EXIT_ERR(MSG) { LOG_ERR(MSG); exit(errno); }

#define LIB_ASSERT(EXPR, MSG) if (!(EXPR)) EXIT_ERR(MSG)


using uint64 = unsigned long long;
using int64 = signed long long;
using uint32 = unsigned int;
using int32 = signed int;
using uint16 = unsigned short;
using int16 = short;
using uint8 = unsigned char;
using int8 = signed char;
using float32 = float;
using float64 = double;


